package com.uzai.console.service.wxpubmanage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.dto.device.DeviceInfoBaseCache;
import com.uzai.common.dto.device.DeviceInfoWxpubCacheDto;
import com.uzai.common.enums.*;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.Math;
import com.uzai.console.common.UzaiRespVo;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.constant.CommonConstant;
import com.uzai.console.dto.BaseDto;
import com.uzai.console.dto.alipaydetail.AlipayDetailCreateDto;
import com.uzai.console.dto.device.deviceauth.DeviceAuthQuery;
import com.uzai.console.dto.feign.wxpub.AuthUnBindDto;
import com.uzai.console.dto.feign.wxpub.AuthUrlDto;
import com.uzai.console.dto.wxpub.DeviceWxpubInfoBuyAuthDto;
import com.uzai.console.dto.wxpub.PriceDto;
import com.uzai.console.dto.wxpub.WxpubAmountDto;
import com.uzai.console.dto.wxpubmanage.*;
import com.uzai.console.entity.*;
import com.uzai.console.entity.wxpubmanage.WxpubInfoEntity;
import com.uzai.console.enums.AlipayStatusEnum;
import com.uzai.console.enums.AlipayTypeEnum;
import com.uzai.console.enums.MerAccDetailSourceTypeEnum;
import com.uzai.console.enums.WxpubDeviceProductEnum;
import com.uzai.console.jsonvo.merbaseconfig.RealNameVerificationJson;
import com.uzai.console.mapper.*;
import com.uzai.console.service.alipaydetail.AlipayDetailService;
import com.uzai.console.service.configplan.ConfigPlanService;
import com.uzai.console.service.deviceauth.DeviceAuthService;
import com.uzai.console.service.feign.WxServerFeignService;
import com.uzai.console.service.merchant.MerchantService;
import com.uzai.console.service.wechatprivate.DeviceWechatInfoCardPayService;
import com.uzai.console.service.wxpubmanage.WxpubComponentService;
import com.uzai.console.service.wxpubmanage.WxpubInfoService;
import com.uzai.console.vo.alipaydetail.businessinfo.DeviceAuthBusinessInfo;
import com.uzai.console.vo.deviceauth.DeviceAuthVo;
import com.uzai.console.vo.wechatprivate.devicewechatinfo.CardBuyResult;
import com.uzai.console.vo.wechatprivate.devicewechatinfo.DeviceAmountVo;
import com.uzai.console.vo.wxpub.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author cen
 * @Date 2022/3/22 0022 10:19
 */
@Service
public class WxpubInfoServiceImpl implements WxpubInfoService {

    public static Logger logger = LoggerFactory.getLogger(WxpubInfoServiceImpl.class);

    @Autowired
    private WxpubInfoMapper mapper;
    @Autowired
    private DeviceWechatInfoMapper deviceWechatInfoMapper;
    @Autowired
    private WxpubComponentService componentService;
    @Autowired
    private WxServerFeignService wxServerFeignService;
    @Autowired
    private DeviceWxworkInfoMapper deviceWxworkInfoMapper;
    @Autowired
    private ConfigPlanService configPlanService;
    @Autowired
    private DevicePriceMapper devicePriceMapper;
    @Autowired
    private DeviceProductMapper deviceProductMapper;
    @Autowired
    private DeviceAuthMapper deviceAuthMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private MerAccDetailMapper merAccDetailMapper;
    @Autowired
    private DeviceAuthDetailMapper deviceAuthDetailMapper;
    @Autowired
    private AlipayDetailService alipayDetailService;
    @Autowired
    private AlipayDetailMapper alipayDetailMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private CdkeysMapper cdkeysMapper;
    @Autowired
    private DeviceWechatInfoCardPayService deviceWechatInfoCardPayService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DeviceAuthService deviceAuthService;
    @Autowired
    private ConfigPlanMapper configPlanMapper;
    @Autowired
    private MerchantService merchantService;

    @Override
    public WxpubInfoEntity queryObject(Long id) {
        return mapper.queryObject(id);
    }

    @Override
    public Page<WxpubInfoEntity> queryList(WxpubInfoListQuery dto) {

        int now = DateUtil.getNowTime();

        //执行分页查询对象
        Page<WxpubInfoEntity> page = new Page<>();
        dto.convert(page);
        List<WxpubInfoEntity> list = mapper.findListByAuthGroup(page, dto);

        //绑定列表查询.
        for (WxpubInfoEntity vo : list) {
            // 查询绑定列表信息
            List<DeviceInfoVo> deviceInfoVos = deviceWechatInfoMapper.queryWxpubBindList(vo.getMerId(), vo.getId());
            List<String> nameList = new ArrayList<>();
            for (DeviceInfoVo infoVo : deviceInfoVos) {
                nameList.add(StringUtils.isNotBlank(infoVo.getDeviceName()) ? infoVo.getDeviceName() : infoVo.getDeviceRemark());
            }
            if (CollectionUtils.isNotEmpty(nameList)) {
                vo.setDeviceInfoStr(StringUtils.join(nameList, "、"));
            }

            //授权信息
            List<DeviceAuthVo> deviceAuthVoList = new ArrayList<>();
            DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
            deviceAuthQuery.setDeviceId(vo.getDeviceId());
            //deviceAuthQuery.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
            List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
            if (deviceAuthList != null && deviceAuthList.size() > 0) {
                for (DeviceAuth deviceAuth : deviceAuthList) {
                    DeviceAuthVo deviceAuthVo = new DeviceAuthVo();
                    BeanUtils.copyProperties(deviceAuth, deviceAuthVo);
                    WxpubDeviceProductKeyEnum wxpubDeviceProductKeyEnum = WxpubDeviceProductKeyEnum.getValue(deviceAuth.getProductCode());
                    if (wxpubDeviceProductKeyEnum != null) {
                        deviceAuthVo.setProductName(wxpubDeviceProductKeyEnum.getDesc());
                    }
                    //到期时间
                    Integer expiretime = Tools.getInteger(deviceAuthVo.getExpireTime());
                    if (expiretime.intValue() <= now) {
                        deviceAuthVo.setExpireStatus(0);  //已到期
                    } else if (expiretime.intValue() > now && expiretime.intValue() <= now + 7 * 24 * 3600) {
                        deviceAuthVo.setExpireStatus(2);  //即将到期
                    } else {
                        deviceAuthVo.setExpireStatus(1);  //未到期
                    }
                    deviceAuthVoList.add(deviceAuthVo);
                }
            }
            //封装PC端授权记录
            vo.setDeviceAuthVoList(deviceAuthVoList);

            if (vo.getConfigId() != null) {
                //查询配置方案信息
                ConfigPlan configPlan = configPlanMapper.selectById(vo.getConfigId(), vo.getMerId());
                if (configPlan != null && StringUtils.isNotBlank(configPlan.getName())) {
                    vo.setConfigPlanName(configPlan.getName());
                }
            }

            vo.setDeviceInfoList(deviceInfoVos);
        }

        page.setRecords(list);
        return page;
    }

    @Override
    public void updateList(WxpubInfoUpdateDto dto) {

        for (Long id : dto.getIds()) {
            //查询机器人信息
            WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(id);
            if (wxpubInfoEntity == null) {
                continue;
            }

            //判断是否修改了配置方案id,如果修改了配置方案id,则需要判断配置方案里会员类型组是否不一样，如果不一样，则不能修改
            if (Tools.getLong(dto.getConfigId()).longValue() != Tools.getLong(wxpubInfoEntity.getConfigId())) {
                ConfigPlan configPlanOld = configPlanMapper.selectById(wxpubInfoEntity.getConfigId(), wxpubInfoEntity.getMerId());
                ConfigPlan configPlanNew = configPlanMapper.selectById(dto.getConfigId(), dto.getMerId());
                if (configPlanOld != null && configPlanNew != null) {
                    if(Tools.getLong(configPlanOld.getUserTypeGroupId()).longValue() != Tools.getLong(configPlanNew.getUserTypeGroupId()).longValue()) {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "机器人id:" + wxpubInfoEntity.getId() + "新修改的配置方案里的会员类型组和旧配置方案里会员类型组不一样");
                    }
                }
            }
        }

        //查询缓存并进行修改
        mapper.updateList(dto);

        //根据id进行查询如果有对应缓存则修改 ,如果没有则进行添加

        List<Long> ids = dto.getIds();

        //缓存处理 .
        for (Long id : ids) {
            Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id));
            if (object == null) {

                WxpubInfoEntity wxpubInfoEntity = queryObject(id);

                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(JSON.toJSONString(wxpubInfoEntity), DeviceInfoWxpubCacheDto.class);

                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id), JSONObject.toJSONString(deviceInfoWxpubCacheDto));

            } else {
                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoWxpubCacheDto.class);

                deviceInfoWxpubCacheDto.setConfigId(dto.getConfigId());

                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id), JSONObject.toJSONString(deviceInfoWxpubCacheDto));
            }
        }

    }

    @Override
    public void addObject(WxpubInfoDto dto) {

    }

    @Override
    public AuthUrlVo queryAuthUrl(BaseDto dto) {
        // 查询是否配置有对应的三方配置
//        WxpubComponentEntity entity = componentService.queryObject(dto.getMerId());
        // 默认授权目标为自己账户
//        int target = 1;

        // 如果商户设置了对应的三方账户信息 则直接采用三方的账号信息
//        if (entity == null || StringUtils.isBlank(entity.getWxAppId()) || StringUtils.isBlank(entity.getWxAppSecret()) || StringUtils.isBlank(entity.getWxAesKey())) {
//            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "三方平台未设置或者相关信息设置为空 , 请检查后再进行公众号添加 . ");
//        }

        AuthUrlDto authUrlDto = new AuthUrlDto();
        authUrlDto.setMerId(dto.getMerId());
        authUrlDto.setTarget(0);
        authUrlDto.setType(DeviceTypeEnum.WX_PUB_VALUE);

        // 通过微服务访问请求链接
        UzaiRespVo<AuthUrlVo> respVo = wxServerFeignService.queryAuthUrl(authUrlDto);

        if (respVo != null && respVo.getData() != null && StringUtils.isNotBlank(respVo.getData().getLoginPageUrl())) {

            String urlRes = respVo.getData().getLoginPageUrl();

            String encode = URLEncoder.encode(urlRes);

            respVo.getData().setLoginPageUrl(CommonConstant.AUTH_URL + encode);
            return respVo.getData();
        } else {
            logger.info("queryAuthUrl req :", JSONObject.toJSONString(authUrlDto));
            logger.info("queryAuthUrl respVo :", JSONObject.toJSONString(respVo));

            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "获取授权链接错误 . ");
        }

    }


    @Override
    public void deleteList(WxpubInfoDeleteDto wxpubInfoDeleteDto) {
        // 取消授权信息 ,

        List<Long> ids = wxpubInfoDeleteDto.getIds();

        if (CollectionUtils.isEmpty(ids)) {
            return;
        }

        List<WxpubInfoEntity> list = mapper.queryListByIds(ids);

        // 完成对应信息处理
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 删除对应列表信息
        mapper.deleteListByIds(ids);

        for (WxpubInfoEntity entity : list) {
            AuthUnBindDto dto = new AuthUnBindDto();
            dto.setWxpubId(entity.getId());
            UzaiRespVo<Boolean> unbind = wxServerFeignService.unbind(dto);
            logger.info("unbind res : {}", JSONObject.toJSONString(unbind));
        }
        // 修改对应微信机器人绑定信息

//        deviceWechatInfoMapper.updateByWbpubIds(ids);


        //删除缓存信息
        for (WxpubInfoEntity entity : list) {
            Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), entity.getId()));
            redisTemplate.delete(object);
        }
    }

    @Override
    public Page<DeviceInfoVo> queryDeviceInfo(WxpubDeviceListQuery dto) {
        //执行分页查询对象
        Page<DeviceInfoVo> page = new Page<>();
        dto.convert(page);
        ArrayList<DeviceInfoVo> list = new ArrayList<>();

        if (dto.getDeviceType() == null || dto.getDeviceType() == DeviceTypeEnum.DT_PC_WECHAT_VALUE) {
            list = deviceWechatInfoMapper.queryUnbindWxpubQuery(page, dto);
        } else if (dto.getDeviceType() == DeviceTypeEnum.DT_WORK_WECHAT_VALUE) {
            list = deviceWxworkInfoMapper.queryUnbindWxpubQuery(page, dto);
        }

        page.setRecords(list);
        return page;

    }

    @Override
    public void bindDeviceList(WxpubDeviceBindDto dto) {

        if (dto.getDeviceType() == null || dto.getDeviceType() == DeviceTypeEnum.DT_PC_WECHAT_VALUE) {
            deviceWechatInfoMapper.updateWxpubIdByIds(dto);

        } else if (dto.getDeviceType() == DeviceTypeEnum.DT_WORK_WECHAT_VALUE) {
            deviceWxworkInfoMapper.updateWxpubIdByIds(dto);
        }

    }

    @Override
    public void bindAllDeviceList(WxpubDeviceListQuery dto) {

        if (dto.getDeviceType() == DeviceTypeEnum.DT_PC_WECHAT_VALUE) {
            List<DeviceInfoVo> deviceInfoVos = deviceWechatInfoMapper.queryListWxpubQuery(dto);
            List<Long> longs = deviceInfoVos.stream().map(DeviceInfoVo::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(longs)) {
                WxpubDeviceBindDto bindDto = new WxpubDeviceBindDto();
                bindDto.setIds(longs);
                bindDto.setMerId(dto.getMerId());
                bindDto.setWxpubId(dto.getWxpubId());
                deviceWechatInfoMapper.updateWxpubIdByIds(bindDto);
            }
        }
    }

    @Override
    public WxpubMenuVo menuQuery(WxpubAddAuthFreeDto wxpubIdDto) {
        //查询数据库里面对应字段并进行展示
        WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(wxpubIdDto.getId());
        WxpubMenuVo vo = new WxpubMenuVo();
        vo.setMenu(wxpubInfoEntity.getMenu());
        return vo;
    }

    @Override
    public void menuUpdate(WxpubMenuDto wxpubMenuDto) {
        //修改菜单设置
        WxpubInfoEntity wxpubInfoEntity = JSONObject.parseObject(JSONObject.toJSONString(wxpubMenuDto), WxpubInfoEntity.class);

        CreateMenuDto dto = new CreateMenuDto();
        dto.setMerId(wxpubMenuDto.getMerId());
        dto.setWxpubId(wxpubMenuDto.getId());
        dto.setMenuStr(wxpubMenuDto.getMenu());

        String menu = wxpubMenuDto.getMenu();
        JSONArray jsonArray = JSONObject.parseArray(menu);
        JSONArray buttonArray = new JSONArray();

        String clickKey = StringUtils.EMPTY;
        Map<String, Object> clickMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject button = (JSONObject) jsonArray.get(i);
                String typeKey = button.getString("typeKey");
                JSONArray subArray = button.getJSONArray("sub_button");
                if (CollectionUtils.isEmpty(subArray)) {
                    //没有下级平台
                    //如果是key则没有下级平台, 直接判断是否是 click点击事件,如果是点击事件则设置对应的id
                    if (StringUtils.equals("click", button.getString("type"))) {

                        if (StringUtils.equals(typeKey, "2")) {
                            clickKey = "click_" + i + "_key";
                            button.put("key", clickKey);
                            clickMap.put(clickKey, button.getJSONArray("text_content"));
                            // 创建一个新的map结构来存储 所有点击事件 用于微信回调处理
                        } else if (StringUtils.equals(typeKey, "5")) {
                            clickKey = "click_" + i + "_key";
                            button.put("key", clickKey);
                            clickMap.put(clickKey, button.getString("personal_id"));
                        }
                    } else if (StringUtils.equals("miniprogram", button.getString("type"))) {
                        String url = button.getString("url");
                        if (StringUtils.isBlank(url)) {
                            button.put("url", "http://3.52youzai.com");
                        }
                    }


                } else {
                    //有对应下级菜单情况
                    JSONArray subArrayNew = new JSONArray();
                    for (int j = 0; j < subArray.size(); j++) {
                        JSONObject subObj = (JSONObject) subArray.get(j);

                        String subTypeKey = subObj.getString("typeKey");
                        //没有下级平台
                        //如果是key则没有下级平台, 直接判断是否是 click点击事件,如果是点击事件则设置对应的id
                        if (StringUtils.equals("click", subObj.getString("type"))) {

                            if (StringUtils.equals(subTypeKey, "2")) {
                                clickKey = "click_" + i + "_" + j + "_typekey_2";
                                subObj.put("key", clickKey);
                                clickMap.put(clickKey, subObj.getJSONArray("text_content"));
                                // 创建一个新的map结构来存储 所有点击事件 用于微信回调处理
                            } else if (StringUtils.equals(subTypeKey, "5")) {
                                clickKey = "click_" + i + "_" + j + "_typekey_5";
                                subObj.put("key", clickKey);
                                clickMap.put(clickKey, subObj.getString("personal_id"));
                            }
                        } else if (StringUtils.equals("miniprogram", subObj.getString("type"))) {
                            String url = subObj.getString("url");
                            if (StringUtils.isBlank(url)) {
                                subObj.put("url", "http://3.52youzai.com");
                            }
                        }
                        subArrayNew.add(subObj);
                    }
                    button.remove("type");
                    button.put("sub_button", subArrayNew);
                }
                buttonArray.add(button);
            }
        }


        wxpubInfoEntity.setMenuClick(JSONObject.toJSONString(clickMap));

        JSONObject menuJson = new JSONObject();
        menuJson.put("button", buttonArray);

        dto.setMenuStr(menuJson.toJSONString());

        // 调用 微服务进行上传菜单功能
        UzaiRespVo<BaseResponse> respVo = wxServerFeignService.createMenu(dto);

        logger.info("meunu update res : {}", JSONObject.toJSONString(respVo));

        //如果没有成功 , 则直接抛出异常页面显示 .
        if (!respVo.getData().isSuccess()) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, respVo.getData().getErrmsg());
        }

        mapper.updateObject(wxpubInfoEntity);

    }

    /**
     * 查询购买公众号授权价格
     *
     * @param priceDto
     * @author liuqi
     * @date 2021/8/25 11:38
     */
    public PriceVo getPrice(PriceDto priceDto) {

        //授权类型(1月卡;2年卡)
        Integer authType = priceDto.getAuthType();
        if (authType == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
        }

        String productCode = WxpubDeviceProductEnum.FL.getValue();
        if (StringUtils.isBlank(productCode)) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入产品编码");
        }

        //查询产品价格
        DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB.getId());
        if (devicePrice == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该产品还未设置价格");
        }

        PriceVo priceVo = new PriceVo();
        priceVo.setPrice(devicePrice.getPrice());

        return priceVo;
    }

    /**
     * 购买授权
     *
     * @param deviceWxpubInfoBuyAuthDto
     * @author liuqi
     * @date 2021/8/25 11:38
     */
    @Transactional
    public DeviceWxpubInfoAddVo buyDeviceAuth(DeviceWxpubInfoBuyAuthDto deviceWxpubInfoBuyAuthDto) {

        //判断是否已经实名验证
        RealNameVerificationJson realNameVerificationJson = merchantService.getRealNameInfo(deviceWxpubInfoBuyAuthDto.getMerId());
        if (realNameVerificationJson == null || StringUtils.isBlank(realNameVerificationJson.getIdCard())) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "需要验证运营商是否实名，未实名需要到【账号设置】中设置实名信息");
        }

        DeviceWxpubInfoAddVo deviceWxpubInfoAddVo = new DeviceWxpubInfoAddVo();
        String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
        Integer now = DateUtil.getNowTime();
        Long merId = deviceWxpubInfoBuyAuthDto.getMerId();

        //取出机器人列表
        List<Long> idList = deviceWxpubInfoBuyAuthDto.getIdList();
        if (idList == null || idList.size() == 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择id");
        }

        //支付类型
        Integer payType = deviceWxpubInfoBuyAuthDto.getPayType();
        if (payType == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入支付类型");
        }

        //产品编号为微信公众号编号
        String productCode_auth = deviceWxpubInfoBuyAuthDto.getProductCode();
        if (StringUtils.isBlank(productCode_auth)) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择授权产品");
        }
        DeviceProduct deviceProduct_auth = deviceProductMapper.selectByCode(productCode_auth);
        if (deviceProduct_auth == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置该微信公众号功能");
        }
        //List<String> productCodeList = JSONObject.parseArray(deviceProduct_auth.getCodes(), String.class);
        //从枚举中获取关联的产品
        WxpubDeviceProductEnum wxpubDeviceProductEnum = WxpubDeviceProductEnum.getValue(deviceProduct_auth.getCode());
        List<String> productCodeList = JSONObject.parseArray(wxpubDeviceProductEnum.getCodes(), String.class);
        if (productCodeList == null || productCodeList.size() == 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还没配置微信公众号功能");
        }

        //判断支付类型
        if (payType.intValue() == PaymentTypeEnum.PAY_BALANCE.getId().intValue()) {//余额支付

            //授权类型(0试用;1月卡;2年卡)
            Integer authType = deviceWxpubInfoBuyAuthDto.getAuthType();
            if (authType == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
            }

            //授权数量
            Integer quantity = deviceWxpubInfoBuyAuthDto.getQuantity();
            if (quantity == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
            }

            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) { //按月购买
                if (quantity.intValue() > 120) { //不能超过120月
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
                }
            } else { //按年购买
                if (quantity.intValue() > 10) { //不能超过10年
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
                }
            }

            //保存到数据库当中的购买月数，按年买需要乘以12月
            Integer quantity_db = 0;

            //总金额
            WxpubAmountDto wxpubAmountDto = new WxpubAmountDto();
            BeanUtils.copyProperties(deviceWxpubInfoBuyAuthDto, wxpubAmountDto);
            wxpubAmountDto.setIdList(idList);
            DeviceAmountVo deviceAmountVo = getAmount(wxpubAmountDto);
            Double amountTotal = Tools.getDouble(deviceAmountVo.getAmountTotal());

            if (amountTotal.doubleValue() <= 0) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择授权时长已经存在");
            }

            //查询产品的总价格
            DevicePrice devicePrice_buy = devicePriceMapper.selectByAuthType(authType, productCode_auth, DeviceTypeEnum.WX_PUB_VALUE);
            if (devicePrice_buy == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置产品的价格");
            }
            //all产品
            Double price_all = Tools.getDouble(devicePrice_buy.getPrice());
            //分别查询该产品包含的产品的总价格
            Double price_total = 0.00D;
            for (String productCode : productCodeList) {
                //查询产品价格
                DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
                if (devicePrice == null) {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置好产品的价格");
                }
                price_total = Math.add(price_total, Tools.getDouble(devicePrice.getPrice()));
            }
            //总单价的优惠
            Double price_discount = Math.sub(price_total, price_all);


            //新的到期时间
            Integer expired_time = 0;

            //保存账户余额
            //处理余额支付信息
            //查询账号信息
            Merchant merchant = merchantMapper.selectById(merId);
            if (merchant == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该运营商不存在");
            }

            //判断余额大小
            Double balance = merchant.getBalance();
            if (balance.doubleValue() < amountTotal.doubleValue()) { //不够支付
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "账户余额不足");
            }

            //修改账户余额
            merchant.setBalance(balance - amountTotal);
            merchant.setUpdateTime(now);
            merchantMapper.updateBalance(merchant);

            //添加账户明细
            MerAccDetail merAccDetail = new MerAccDetail();
            merAccDetail.setId(IdWorker.getId());
            merAccDetail.setMerId(merchant.getId());
            merAccDetail.setOperateType(2);//支出
            merAccDetail.setMoney(merchant.getBalance());
            merAccDetail.setCgMoney(amountTotal);
            merAccDetail.setSourceType(MerAccDetailSourceTypeEnum.WXPUB_AUTH.getId());
            merAccDetail.setSubtype(productCode_auth);
            merAccDetail.setTradeno(trandeNo);
            merAccDetail.setCreateTime(now);
            merAccDetail.setUpdateTime(now);
            merAccDetailMapper.insert(merAccDetail);

            //循环批量操作的机器人
            for (Long deviceUniqueId : idList) {

                //查询机器人信息
                WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(deviceUniqueId);
                if (wxpubInfoEntity == null) {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的公众号不存在");
                }
                String deviceId = wxpubInfoEntity.getDeviceId();

                //本次授权开始时间默认为现在
                Integer begin_time = deviceAuthService.selectEarliestAuthByDeviceIdAndProductCodeList(deviceId, productCodeList, now);

                //选择全包套餐包时的到期时间，如果单个基础包购买，则另外判断到期时间
                if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) {//按月购买
                    //新的到期时间=现在+月数*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 30 * 24 * 3600;
                    quantity_db = quantity;
                } else {//按年购买
                    //新的到期时间=现在+年数*12月*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 12 * 30 * 24 * 3600;
                    quantity_db = quantity * 12;
                }

                //判断购买的产品类型（全包类型需要补差价）
                if (productCodeList.size() == 1) { //单个基础包，则需重新设置到期时间，直接时间累加
                    Integer beginTime_one = 0;
                    Integer expireTime_one = 0;
                    String productCode = productCodeList.get(0);
                    //查询产品价格
                    DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
                    if (devicePrice == null) {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置机器人该端的购买价格");
                    }
                    //单个机器人总金额=单价*购买时间数
                    Double amount = Math.mul(Tools.getDouble(devicePrice.getPrice()), quantity, 2);

                    //添加机器人授权表-如果没有则新增，有则修改
                    DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                    if (deviceAuth != null) {//修改
                        //判断旧到期时间是否已经过期
                        Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                        if (old_expireTime <= now) {//已经到期，则从今天开始算
                            beginTime_one = now;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        } else {
                            beginTime_one = old_expireTime;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        }
                        deviceAuth.setExpireTime(expireTime_one);
                        deviceAuth.setUpdateTime(now);
                        deviceAuth.setAuthType(authType);
                        deviceAuthMapper.updateById(deviceAuth);
                    } else {
                        deviceAuth = new DeviceAuth();
                        deviceAuth.setId(IdWorker.getId());
                        deviceAuth.setDeviceId(wxpubInfoEntity.getDeviceId());
                        deviceAuth.setDeviceUniqueId(wxpubInfoEntity.getId());
                        deviceAuth.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                        deviceAuth.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                        deviceAuth.setProductCode(productCode);
                        beginTime_one = now;
                        expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        deviceAuth.setExpireTime(expireTime_one);
                        deviceAuth.setCreateTime(now);
                        deviceAuth.setUpdateTime(now);
                        deviceAuth.setAuthType(authType);
                        deviceAuthMapper.insert(deviceAuth);
                    }

                    //添加机器人授权明细表
                    DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                    deviceAuthDetail.setId(IdWorker.getId());
                    deviceAuthDetail.setMerId(deviceWxpubInfoBuyAuthDto.getMerId());
                    deviceAuthDetail.setDeviceUniqueId(wxpubInfoEntity.getId());
                    deviceAuthDetail.setDeviceId(wxpubInfoEntity.getDeviceId());
                    deviceAuthDetail.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                    deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                    deviceAuthDetail.setProductCode(productCode);
                    deviceAuthDetail.setAuthType(deviceWxpubInfoBuyAuthDto.getAuthType());
                    deviceAuthDetail.setQuantity(quantity_db); //试用为0
                    deviceAuthDetail.setBeginTime(beginTime_one);
                    deviceAuthDetail.setExpireTime(expireTime_one);
                    deviceAuthDetail.setPayTime(now);
                    deviceAuthDetail.setPayType(deviceWxpubInfoBuyAuthDto.getPayType());
                    deviceAuthDetail.setTradeno(trandeNo);
                    deviceAuthDetail.setAmount(amount);
                    deviceAuthDetail.setRemark("余额支付");
                    deviceAuthDetail.setCreateTime(now);
                    deviceAuthDetail.setUpdateTime(now);
                    deviceAuthDetailMapper.insert(deviceAuthDetail);
                } else { //全包产品

                    for (String productCode : productCodeList) {

                        //查询产品价格
                        DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
                        if (devicePrice == null) {
                            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置公众号该产品的购买价格");
                        }

                        //产品单价
                        Double product_price = Tools.getDouble(devicePrice.getPrice());
                        //计算优惠后的产品单价 = 单价- 单价/总价 * 总优惠价
                        Double product_price_discount = Math.sub(product_price, Math.mul(Math.div(product_price, price_total), price_discount, 2));

                        //查询旧授权
                        DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                        //还未授权
                        if (deviceAuth == null) {
                            //封装产品授权记录
                            DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                            deviceAuthDetail.setId(IdWorker.getId());
                            deviceAuthDetail.setMerId(merId);
                            deviceAuthDetail.setDeviceUniqueId(wxpubInfoEntity.getId());
                            deviceAuthDetail.setDeviceId(wxpubInfoEntity.getDeviceId());
                            deviceAuthDetail.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                            deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                            deviceAuthDetail.setProductCode(productCode);
                            deviceAuthDetail.setAuthType(authType);
                            deviceAuthDetail.setQuantity(quantity_db);
                            deviceAuthDetail.setPayTime(now);
                            deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                            deviceAuthDetail.setTradeno(trandeNo);
                            deviceAuthDetail.setRemark("余额支付");
                            deviceAuthDetail.setCreateTime(now);
                            deviceAuthDetail.setUpdateTime(now);
                            deviceAuthDetail.setAmount(amountTotal);
                            deviceAuthDetail.setBeginTime(begin_time);
                            deviceAuthDetail.setExpireTime(expired_time);
                            //插入授权数据明细
                            deviceAuthDetailMapper.insert(deviceAuthDetail);

                            //插入授权数据
                            //添加机器人授权表
                            deviceAuth = new DeviceAuth();
                            deviceAuth.setId(IdWorker.getId());
                            deviceAuth.setDeviceId(wxpubInfoEntity.getDeviceId());
                            deviceAuth.setDeviceUniqueId(wxpubInfoEntity.getId());
                            deviceAuth.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                            deviceAuth.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                            deviceAuth.setAuthType(authType);
                            deviceAuth.setProductCode(productCode);
                            //新授权，到期时间从今天开始算
                            deviceAuth.setExpireTime(expired_time);
                            deviceAuth.setCreateTime(now);
                            deviceAuth.setUpdateTime(now);
                            deviceAuthMapper.insert(deviceAuth);

                        } else { //授权存在，需判断授权的结束时间
                            //旧到期时间
                            Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                            //判断旧授权是否已经过期，
                            if (old_expireTime <= now) { //已经过期
                                //封装产品授权记录
                                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                                deviceAuthDetail.setId(IdWorker.getId());
                                deviceAuthDetail.setMerId(merId);
                                deviceAuthDetail.setDeviceUniqueId(wxpubInfoEntity.getId());
                                deviceAuthDetail.setDeviceId(wxpubInfoEntity.getDeviceId());
                                deviceAuthDetail.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                                deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                                deviceAuthDetail.setProductCode(productCode);
                                deviceAuthDetail.setAuthType(authType);
                                deviceAuthDetail.setQuantity(quantity_db);
                                deviceAuthDetail.setPayTime(now);
                                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                                deviceAuthDetail.setTradeno(trandeNo);
                                deviceAuthDetail.setRemark("余额支付");
                                deviceAuthDetail.setCreateTime(now);
                                deviceAuthDetail.setUpdateTime(now);
                                deviceAuthDetail.setAmount(amountTotal);
                                deviceAuthDetail.setBeginTime(begin_time);
                                deviceAuthDetail.setExpireTime(expired_time);
                                //插入授权数据明细
                                deviceAuthDetailMapper.insert(deviceAuthDetail);

                                //更新授权记录
                                deviceAuth.setAuthType(authType);
                                deviceAuth.setExpireTime(expired_time);
                                deviceAuth.setUpdateTime(now);
                                deviceAuthMapper.updateById(deviceAuth);

                                //旧到期时间大于当前时间，且小于授权结束时间，则补差价
                            } else if (old_expireTime > now && old_expireTime < expired_time) {

                                //封装产品授权记录
                                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                                deviceAuthDetail.setId(IdWorker.getId());
                                deviceAuthDetail.setMerId(merId);
                                deviceAuthDetail.setDeviceUniqueId(wxpubInfoEntity.getId());
                                deviceAuthDetail.setDeviceId(wxpubInfoEntity.getDeviceId());
                                deviceAuthDetail.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                                deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                                deviceAuthDetail.setProductCode(productCode);
                                deviceAuthDetail.setAuthType(authType);
                                deviceAuthDetail.setQuantity(quantity_db);
                                deviceAuthDetail.setPayTime(now);
                                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                                deviceAuthDetail.setTradeno(trandeNo);
                                deviceAuthDetail.setRemark("余额支付");
                                deviceAuthDetail.setCreateTime(now);
                                deviceAuthDetail.setUpdateTime(now);
                                deviceAuthDetail.setAmount(amountTotal);
                                deviceAuthDetail.setBeginTime(begin_time);
                                deviceAuthDetail.setExpireTime(expired_time);
                                //插入授权数据明细
                                deviceAuthDetailMapper.insert(deviceAuthDetail);
                                //更新授权记录
                                deviceAuth.setAuthType(authType);
                                deviceAuth.setExpireTime(expired_time);
                                deviceAuth.setUpdateTime(now);
                                deviceAuthMapper.updateById(deviceAuth);
                            }
                        }
                    }
                }

                //封装机器人授权信息
                List<DeviceInfoBaseCache.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();
                //查询该机器人的所有产品授权信息
                DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
                deviceAuthQuery.setDeviceId(wxpubInfoEntity.getDeviceId());
                List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
                if (deviceAuthList != null && deviceAuthList.size() > 0) {
                    for (DeviceAuth deviceAuth : deviceAuthList) {
                        //机器人redis缓存信息-产品授权
                        DeviceInfoBaseCache.DeviceProductAuth deviceProductAuth = new DeviceInfoBaseCache.DeviceProductAuth();
                        deviceProductAuth.setAuthType(deviceAuth.getAuthType());
                        deviceProductAuth.setExpireTime(deviceAuth.getExpireTime());
                        deviceProductAuth.setProductCode(deviceAuth.getProductCode());
                        deviceProductAuthList.add(deviceProductAuth);
                    }

                    //保存缓存
                    Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()));
                    if (object != null) { //修改
                        DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoWxpubCacheDto.class);
                        if (deviceInfoWxpubCacheDto != null) {
                            deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                            if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                                deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                            }
                        }
                        //更新移动端机器人redis
                        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
                    } else {//新增
                        DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = new DeviceInfoWxpubCacheDto();
                        deviceInfoWxpubCacheDto.setMerId(wxpubInfoEntity.getMerId());
                        deviceInfoWxpubCacheDto.setWxAppId(wxpubInfoEntity.getWxAppId());
                        deviceInfoWxpubCacheDto.setWxAppSecret(wxpubInfoEntity.getWxAppSecret());
                        deviceInfoWxpubCacheDto.setTarget(wxpubInfoEntity.getTarget());
                        deviceInfoWxpubCacheDto.setConfigId(wxpubInfoEntity.getConfigId());
                        deviceInfoWxpubCacheDto.setDeviceId(wxpubInfoEntity.getDeviceId());
                        deviceInfoWxpubCacheDto.setDeviceUniqueId(wxpubInfoEntity.getId());
                        deviceInfoWxpubCacheDto.setMsgHandler(DeviceTypeEnum.WX_PUB.getId());
                        deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                        if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                            deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                        }
                        //更新PC端机器人redis
                        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
                    }
                }
            }
        } else if (payType.intValue() == PaymentTypeEnum.PAY_ALIPAY.getId().intValue()) { //支付宝支付
            //授权类型(0试用;1月卡;2年卡)
            Integer authType = deviceWxpubInfoBuyAuthDto.getAuthType();
            if (authType == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
            }

            //授权数量
            Integer quantity = deviceWxpubInfoBuyAuthDto.getQuantity();
            if (quantity == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
            }

            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) { //按月购买
                if (quantity.intValue() > 120) { //不能超过120月
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
                }
            } else { //按年购买
                if (quantity.intValue() > 10) { //不能超过10年
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
                }
            }

            //保存到数据库当中的购买月数，按年买需要乘以12月
            Integer quantity_db = 0;

            //总金额
            WxpubAmountDto wxpubAmountDto = new WxpubAmountDto();
            BeanUtils.copyProperties(deviceWxpubInfoBuyAuthDto, wxpubAmountDto);
            wxpubAmountDto.setIdList(idList);
            DeviceAmountVo deviceAmountVo = getAmount(wxpubAmountDto);
            Double amountTotal = Tools.getDouble(deviceAmountVo.getAmountTotal());

            if (amountTotal.doubleValue() <= 0) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择授权时长已经存在");
            }

            //新的到期时间
            Integer expired_time = 0;

            //添加支付宝账单
            AlipayDetail alipayDetail = new AlipayDetail();
            alipayDetail.setId(IdWorker.getId());
            alipayDetail.setMerId(deviceWxpubInfoBuyAuthDto.getMerId());
            alipayDetail.setTradeno(trandeNo);
            alipayDetail.setType(AlipayTypeEnum.DEVICE_WXPUB_AUTH.getId()); //续费微信公众号
            alipayDetail.setSubtype(productCode_auth);

            //业务信息
            DeviceAuthBusinessInfo deviceAuthBusinessInfo = new DeviceAuthBusinessInfo();
            deviceAuthBusinessInfo.setDeviceUniqueIdList(deviceWxpubInfoBuyAuthDto.getIdList());
            deviceAuthBusinessInfo.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
            deviceAuthBusinessInfo.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
            deviceAuthBusinessInfo.setAuthType(deviceWxpubInfoBuyAuthDto.getAuthType());
            deviceAuthBusinessInfo.setQuantity(quantity);
            deviceAuthBusinessInfo.setAmount(amountTotal);
            deviceAuthBusinessInfo.setProductCode(productCode_auth);

            //查询产品价格
            DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode_auth, DeviceTypeEnum.WX_PUB_VALUE);
            if (devicePrice == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置微信公众号的购买价格");
            }
            deviceAuthBusinessInfo.setPrice(devicePrice.getPrice());
            alipayDetail.setBusinessInfo(Tools.getStrEmpty(JSONObject.toJSONString(deviceAuthBusinessInfo)));

            alipayDetail.setAmount(amountTotal);
            alipayDetail.setStatus(AlipayStatusEnum.WAIT_BUYER_PAY.getId()); //等待付款
            alipayDetail.setCreateTime(now);
            alipayDetail.setUpdateTime(now);

            //请求支付宝申请订单
            AlipayDetailCreateDto alipayDetailCreateDto = new AlipayDetailCreateDto();
            alipayDetailCreateDto.setOutTradeNo(alipayDetail.getTradeno());
            alipayDetailCreateDto.setTotalAmount(alipayDetail.getAmount());
            alipayDetailCreateDto.setSubject(AlipayTypeEnum.DEVICE_WXPUB_AUTH.getDesc());
            String alipayUrl = alipayDetailService.createAlipayDetail(alipayDetailCreateDto);
            if (StringUtils.isNotBlank(alipayUrl)) {
                alipayDetail.setAlipayUrl(alipayUrl);
                //插入支付宝账单
                alipayDetailMapper.insertSelective(alipayDetail);
                //返回支付页面
                deviceWxpubInfoAddVo.setAlipayUrl(uzaiConsoleSysConfig.getAlipayPaypageUrl() + "?id=" + alipayDetail.getId());
            } else {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "调用支付宝失败");
            }
        } else if (payType.intValue() == PaymentTypeEnum.PAY_CARDID.getId().intValue()) { //卡密支付
            //返回每个设备对于卡密的充值结果信息
            List<CardBuyResult> cardBuyResultList = new ArrayList<>();
            deviceWxpubInfoAddVo.setCardBuyResultList(cardBuyResultList);
            //取出卡密列表
            List<String> cardList = deviceWxpubInfoBuyAuthDto.getCardList();
            if (cardList == null || cardList.size() == 0) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入卡密");
            }

            //循环设备id列表
            for (int i = 0; i < idList.size(); i++) {
                //卡密购买返回结果
                CardBuyResult cardBuyResult = new CardBuyResult();
                cardBuyResult.setMsg("购买失败");
                //先封装近返回list
                cardBuyResultList.add(cardBuyResult);

                try { //每个设备单独提交
                    Long deviceUniqueId = idList.get(i);
                    WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(deviceUniqueId);
                    if (wxpubInfoEntity != null) {
                        cardBuyResult.setDeviceName(wxpubInfoEntity.getDeviceName()); //返回设备昵称
                        if (i < cardList.size()) {
                            //取出对于下标的卡密
                            String card = cardList.get(i);
                            cardBuyResult.setCard(card);  //返回卡密信息
                            //查询该卡信息
                            Cdkeys cdkeys = cdkeysMapper.selectByCard(card);
                            if (cdkeys == null) {
                                cardBuyResult.setMsg("卡密错误");
                                continue;
                            }

                            if (cdkeys.getProductType().intValue() == CdkeysProductTypeEnum.ALL.getId().intValue()) {
                                if (!productCode_auth.equals(WxpubDeviceProductEnum.ALL.getValue())) {
                                    cardBuyResult.setMsg("卡密类型不一致，当前卡为 公众号 全部功能 卡");
                                    continue;
                                }
                            } else if (cdkeys.getProductType().intValue() == CdkeysProductTypeEnum.FL.getId().intValue()) {
                                if (!productCode_auth.equals(WxpubDeviceProductEnum.FL.getValue())) {
                                    cardBuyResult.setMsg("卡密类型不一致，当前卡为 公众号 返利 卡");
                                    continue;
                                }
                            } else if (cdkeys.getProductType().intValue() == CdkeysProductTypeEnum.UZAICHAT.getId().intValue()) {
                                if (!productCode_auth.equals(WxpubDeviceProductEnum.UZAICHAT.getValue())) {
                                    cardBuyResult.setMsg("卡密类型不一致，当前卡为 公众号 悠聊 卡");
                                    continue;
                                }
                            }

                            if (Tools.getInteger(cdkeys.getDeviceTypeId()).intValue() != DeviceTypeEnum.WX_PUB.getId()) {//公众号
                                cardBuyResult.setMsg("不是公众号卡密");
                                continue;
                            }
                            if (cdkeys.getStatus().intValue() == CdkeysStatusEnum.USED.getId().intValue()) {//卡密已使用
                                cardBuyResult.setMsg("卡密已使用");
                                continue;
                            }
                            if (cdkeys.getStatus().intValue() == CdkeysStatusEnum.INVALID.getId().intValue()) {//卡密已作废
                                cardBuyResult.setMsg("卡密已作废");
                                continue;
                            }
                            if (cdkeys.getStatus().intValue() == CdkeysStatusEnum.STOCK.getId().intValue()) {//卡密还未出库
                                cardBuyResult.setMsg("卡密还未出库");
                                continue;
                            }
                            if (cdkeys.getStatus().intValue() == CdkeysStatusEnum.OUTSTOCK.getId().intValue()) {//出库状态
                                deviceWechatInfoCardPayService.buyWxpubAuthByCard(wxpubInfoEntity, DeviceTypeEnum.WX_PUB.getId(), cdkeys, now, trandeNo, productCodeList);
                                cardBuyResult.setMsg("购买成功");
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("--公众号授权卡密支付失败--error={}", e);
                    cardBuyResult.setMsg("购买失败");
                }
            }
        }
        return deviceWxpubInfoAddVo;
    }

    /**
     * 查询购买总金额
     *
     * @param wxpubAmountDto
     * @author liuqi
     * @date 2021/8/25 11:38
     */
    public DeviceAmountVo getAmount(WxpubAmountDto wxpubAmountDto) {

        //授权类型(1月卡;2年卡)
        Integer authType = wxpubAmountDto.getAuthType();
        if (authType == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
        }

        //购买数量
        Integer quantity = wxpubAmountDto.getQuantity();
        if (quantity == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
        }

        if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) { //按月购买
            if (quantity.intValue() > 120) { //不能超过120月
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
            }
        } else { //按年购买
            if (quantity.intValue() > 10) { //不能超过10年
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
            }
        }

        //返回对象
        DeviceAmountVo deviceAmountVo = new DeviceAmountVo();
        //封装机器人授权信息
        List<DeviceAmountVo.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();

        //设备id
        List<Long> idList = wxpubAmountDto.getIdList();
        if (idList == null || idList.size() == 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择需要购买授权的微信公众号");
        }

        //购买产品
        String productCode_buy = wxpubAmountDto.getProductCode();
        if (StringUtils.isBlank(productCode_buy)) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择购买产品功能");
        }
        DeviceProduct deviceProduct_buy = deviceProductMapper.selectByCode(productCode_buy);
        if (deviceProduct_buy == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统未配置该产品功能");
        }
        //List<String> productCodeList_buy = JSONObject.parseArray(deviceProduct_buy.getCodes(), String.class);
        //从枚举中获取关联的产品
        WxpubDeviceProductEnum wxpubDeviceProductEnum = WxpubDeviceProductEnum.getValue(deviceProduct_buy.getCode());
        List<String> productCodeList_buy = JSONObject.parseArray(wxpubDeviceProductEnum.getCodes(), String.class);
        if (productCodeList_buy == null || productCodeList_buy.size() == 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还没配置该产品功能信息");
        }

        //查询产品的总价格
        DevicePrice devicePrice_buy = devicePriceMapper.selectByAuthType(authType, productCode_buy, DeviceTypeEnum.WX_PUB_VALUE);
        if (devicePrice_buy == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置产品的价格");
        }
        //all产品
        Double price_all = Tools.getDouble(devicePrice_buy.getPrice());
        //分别查询该产品包含的产品的总价格
        Double price_total = 0.00D;
        for (String productCode : productCodeList_buy) {
            //查询产品价格
            DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
            if (devicePrice == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置好产品的价格");
            }
            price_total = Math.add(price_total, Tools.getDouble(devicePrice.getPrice()));
        }
        //总单价的优惠
        Double price_discount = Math.sub(price_total, price_all);

        if (price_discount.doubleValue() < 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统产品价格设置错误");
        }

        //当天时间
        Integer now = DateUtil.getNowTime();
        //总金额
        Double amount_totle = 0.00D;
        //新的到期时间
        Integer expired_time = 0;
        //授权的天数
        Integer authDays = 0;
        //保存到数据库当中的购买月数，按年买需要乘以12月
        Integer quantity_db = 0;

        //循环批量操作的公众号
        for (Long deviceUniqueId : idList) {

            //查询公众号信息
            WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(deviceUniqueId);
            if (wxpubInfoEntity == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的公众号不存在");
            }
            String deviceId = wxpubInfoEntity.getDeviceId();

            //本次授权开始时间默认为现在
            Integer begin_time = now;

            //查询该设备最早授权时间,如果不为空，则取最早授权时间为本次授权开始时间
            begin_time = deviceAuthService.selectEarliestAuthByDeviceIdAndProductCodeList(deviceId, productCodeList_buy, now);


            //选择全包套餐包时的到期时间，如果单个基础包购买，则另外判断到期时间
            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) {//按月购买
                //新的到期时间=现在+月数*30天*24小时*3600秒
                expired_time = begin_time + quantity * 30 * 24 * 3600;
                quantity_db = quantity;
                authDays = quantity_db * 30;
            } else {//按年购买
                //新的到期时间=现在+年数*12月*30天*24小时*3600秒
                expired_time = begin_time + quantity * 12 * 30 * 24 * 3600;
                quantity_db = quantity * 12;
                authDays = quantity_db * 30;
            }

            //判断购买的产品类型（全包类型需要补差价）
            if (productCodeList_buy.size() == 1) { //单个基础包，则需重新设置到期时间，直接时间累加
                //单个产品授权开始时间
                Integer beginTime_one = 0;
                //单个产品授权结束时间
                Integer expireTime_one = 0;
                //单个产品授权天数
                Integer authDays_one = quantity_db * 30;
                String productCode = productCodeList_buy.get(0);
                //查询产品价格
                DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
                if (devicePrice == null) {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置公众号该产品的购买价格");
                }
                //单个机器人总金额=单价*购买时间数
                Double amount = Math.mul(Tools.getDouble(devicePrice.getPrice()), quantity);
                //总金额累加
                amount_totle = Math.add(amount_totle, amount);

                //计算产品授权记录
                //添加机器人授权表-如果没有则新增，有则修改
                DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                if (deviceAuth != null) {//修改
                    //判断旧到期时间是否已经过期
                    Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                    if (old_expireTime <= now) {//已经到期，则从今天开始算
                        beginTime_one = now;
                        expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                    } else {
                        beginTime_one = old_expireTime;
                        expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                    }
                } else {
                    beginTime_one = now;
                    expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                }

                //机器人redis缓存信息-产品授权
                DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                deviceProductAuth.setAuthDays(authDays_one);
                deviceProductAuth.setExpireTime(expireTime_one);
                deviceProductAuth.setProductCode(productCode);
                deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                deviceProductAuthList.add(deviceProductAuth);

            } else { //全包产品

                //单个机器人总金额=单价*购买时间数
                Double amount = Math.mul(Tools.getDouble(devicePrice_buy.getPrice()), quantity);

                for (String productCode : productCodeList_buy) {

                    //单个产品授权天数
                    Integer authDays_one = quantity_db * 30;

                    //查询产品价格
                    DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.WX_PUB_VALUE);
                    if (devicePrice == null) {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置公众号该产品的购买价格");
                    }

                    //产品单价
                    Double product_price = devicePrice.getPrice();
                    //计算优惠后的产品单价 = 单价- 单价/总价 * 总优惠价
                    Double product_price_discount = Math.sub(product_price, Math.mul(Math.div(product_price, price_total), price_discount, 2));

                    //查询旧授权
                    DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                    //还未授权，不需要补差价
                    if (deviceAuth == null) {
                        //机器人redis缓存信息-产品授权
                        DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                        deviceProductAuth.setAuthDays(authDays_one);
                        deviceProductAuth.setExpireTime(expired_time);
                        deviceProductAuth.setProductCode(productCode);
                        deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                        deviceProductAuthList.add(deviceProductAuth);
                    } else { //授权存在，需判断授权的结束时间
                        //旧到期时间
                        Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                        //判断旧授权是否已经过期，
                        if (old_expireTime <= now) { //已经过期,也不需要补差价
                            //机器人redis缓存信息-产品授权
                            DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                            deviceProductAuth.setAuthDays(authDays_one);
                            deviceProductAuth.setExpireTime(expired_time);
                            deviceProductAuth.setProductCode(productCode);
                            deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                            deviceProductAuthList.add(deviceProductAuth);
                        } else if (old_expireTime > now && old_expireTime < expired_time) {
                            //需要补差价
                            Double differenceAmount = 0.00D;
                            //减去当前的时间，除以3600秒，再除以24小时取整，即是相差的天数
                            Double days = Math.div((old_expireTime - begin_time), 3600 * 24, 2);
                            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId()) {//按月购买的
                                differenceAmount = Math.mul(Math.div(product_price_discount, 30), days, 2);
                            } else {//按年购买的
                                differenceAmount = Math.mul(Math.div(product_price_discount, 360), days, 2);
                            }
                            //单产品支付的金额
                            amount = Math.sub(amount, differenceAmount);

                            //授权的天数
                            authDays_one = authDays_one - days.intValue();

                            //机器人redis缓存信息-产品授权
                            DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                            deviceProductAuth.setAuthDays(authDays_one);
                            deviceProductAuth.setExpireTime(expired_time);
                            deviceProductAuth.setProductCode(productCode);
                            deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                            deviceProductAuthList.add(deviceProductAuth);

                        } else {
                            //需要补差价
                            Double differenceAmount = 0.00D;
                            //全额退款
                            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId()) {//按月购买的
                                differenceAmount = Math.mul(Math.div(product_price_discount, 30), authDays_one, 2);
                            } else {
                                differenceAmount = Math.mul(Math.div(product_price_discount, 360), authDays_one, 2);
                            }
                            //单产品支付的金额
                            amount = Math.sub(amount, differenceAmount);
                        }
                    }
                }
                //总金额累加
                amount_totle = Math.add(amount_totle, amount);
            }
        }
        deviceAmountVo.setAmountTotal(amount_totle);
        deviceAmountVo.setDeviceProductAuthList(deviceProductAuthList);
        return deviceAmountVo;
    }

    /**
     * 添加微信公众号免费试用期授权
     *
     * @param wxpubAddAuthFreeDto
     * @author liuqi
     * @date 2021/8/25 11:38
     */
    @Transactional
    public void addWxpubAuthFree(@RequestBody WxpubAddAuthFreeDto wxpubAddAuthFreeDto) {

        Long deviceUniqueId = wxpubAddAuthFreeDto.getId();
        if (deviceUniqueId == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入公众号设备唯一id");
        }

        //查询机器人信息
        WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(deviceUniqueId);
        if (wxpubInfoEntity == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该公众号不存在");
        }

        //产品编号为微信公众号编号
        String productCode_auth = WxpubDeviceProductEnum.ALL.getValue();
        if (StringUtils.isBlank(productCode_auth)) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择授权产品");
        }
        DeviceProduct deviceProduct_auth = deviceProductMapper.selectByCode(productCode_auth);
        if (deviceProduct_auth == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置该微信公众号功能");
        }
        //List<String> productCodeList = JSONObject.parseArray(deviceProduct_auth.getCodes(), String.class);
        //从枚举中获取关联的产品
        WxpubDeviceProductEnum wxpubDeviceProductEnum = WxpubDeviceProductEnum.getValue(deviceProduct_auth.getCode());
        List<String> productCodeList = JSONObject.parseArray(wxpubDeviceProductEnum.getCodes(), String.class);
        if (productCodeList == null || productCodeList.size() == 0) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还没配置微信公众号功能");
        }

        //查询该设备最早授权时间,如果不为空，则表示该公众号已经授权过，不能免费试用
        DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
        deviceAuthQuery.setDeviceId(wxpubInfoEntity.getDeviceId());
        List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
        if (deviceAuthList != null && deviceAuthList.size() > 0) {//授权存在，则刷新缓存就行
            //封装机器人免费试用信息
            List<DeviceInfoBaseCache.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();
            for (DeviceAuth deviceAuth : deviceAuthList) {
                //机器人redis缓存信息-产品授权
                DeviceInfoBaseCache.DeviceProductAuth deviceProductAuth = new DeviceInfoBaseCache.DeviceProductAuth();
                deviceProductAuth.setAuthType(deviceAuth.getAuthType());
                deviceProductAuth.setExpireTime(deviceAuth.getExpireTime());
                deviceProductAuth.setProductCode(deviceAuth.getProductCode());
                deviceProductAuthList.add(deviceProductAuth);
            }

            //保存缓存
            Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()));
            if (object != null) { //修改
                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoWxpubCacheDto.class);
                if (deviceInfoWxpubCacheDto != null) {
                    deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                    if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                        deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                    }
                }
                //更新移动端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
            } else {//新增
                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = new DeviceInfoWxpubCacheDto();
                deviceInfoWxpubCacheDto.setMerId(wxpubInfoEntity.getMerId());
                deviceInfoWxpubCacheDto.setWxAppId(wxpubInfoEntity.getWxAppId());
                deviceInfoWxpubCacheDto.setWxAppSecret(wxpubInfoEntity.getWxAppSecret());
                deviceInfoWxpubCacheDto.setTarget(wxpubInfoEntity.getTarget());
                deviceInfoWxpubCacheDto.setConfigId(wxpubInfoEntity.getConfigId());
                deviceInfoWxpubCacheDto.setDeviceId(wxpubInfoEntity.getDeviceId());
                deviceInfoWxpubCacheDto.setDeviceUniqueId(wxpubInfoEntity.getId());
                deviceInfoWxpubCacheDto.setMsgHandler(DeviceTypeEnum.WX_PUB.getId());
                deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                    deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                }
                //更新PC端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
            }

        } else {//授权不存在，则新增试用期授权
            //封装机器人免费试用信息
            List<DeviceInfoBaseCache.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();

            String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();

            int now = DateUtil.getNowTime();
            //判断购买的产品类型（全包类型需要补差价）
            for (String productCode : productCodeList) { //单个基础包，则需重新设置到期时间，直接时间累加
                Integer expired_time = now + 5 * 24 * 3600;
                //机器人redis缓存信息-产品授权
                DeviceInfoBaseCache.DeviceProductAuth deviceProductAuth = new DeviceInfoBaseCache.DeviceProductAuth();
                deviceProductAuth.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceProductAuth.setExpireTime(expired_time);
                deviceProductAuth.setProductCode(productCode);
                deviceProductAuthList.add(deviceProductAuth);

                //封装设备产品授权记录明细
                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                deviceAuthDetail.setId(IdWorker.getId());
                deviceAuthDetail.setMerId(wxpubInfoEntity.getMerId());
                deviceAuthDetail.setDeviceUniqueId(wxpubInfoEntity.getId());
                deviceAuthDetail.setDeviceId(wxpubInfoEntity.getDeviceId());
                deviceAuthDetail.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                deviceAuthDetail.setProductCode(productCode);
                deviceAuthDetail.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceAuthDetail.setQuantity(0); //试用为0
                deviceAuthDetail.setPayTime(now);
                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                deviceAuthDetail.setTradeno(trandeNo);
                deviceAuthDetail.setRemark("试用期");
                deviceAuthDetail.setCreateTime(now);
                deviceAuthDetail.setUpdateTime(now);
                deviceAuthDetail.setAmount(0.00);
                deviceAuthDetail.setBeginTime(now);
                deviceAuthDetail.setExpireTime(expired_time);
                //插入授权数据明细
                deviceAuthDetailMapper.insert(deviceAuthDetail);

                //添加机器人授权表
                DeviceAuth deviceAuth = new DeviceAuth();
                deviceAuth.setId(IdWorker.getId());
                deviceAuth.setDeviceId(wxpubInfoEntity.getDeviceId());
                deviceAuth.setDeviceUniqueId(wxpubInfoEntity.getId());
                deviceAuth.setDeviceType(DeviceTypeEnum.WX_PUB.getKey());
                deviceAuth.setDeviceTypeId(DeviceTypeEnum.WX_PUB.getId());
                deviceAuth.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceAuth.setProductCode(productCode);
                //新授权，到期时间从今天开始算
                deviceAuth.setExpireTime(expired_time);
                deviceAuth.setCreateTime(now);
                deviceAuth.setUpdateTime(now);
                deviceAuthMapper.insert(deviceAuth);
            }

            //保存缓存
            Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()));
            if (object != null) { //修改
                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoWxpubCacheDto.class);
                if (deviceInfoWxpubCacheDto != null) {
                    deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                    if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                        deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                    }
                }
                //更新移动端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
            } else {//新增
                DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = new DeviceInfoWxpubCacheDto();
                deviceInfoWxpubCacheDto.setMerId(wxpubInfoEntity.getMerId());
                deviceInfoWxpubCacheDto.setWxAppId(wxpubInfoEntity.getWxAppId());
                deviceInfoWxpubCacheDto.setWxAppSecret(wxpubInfoEntity.getWxAppSecret());
                deviceInfoWxpubCacheDto.setTarget(wxpubInfoEntity.getTarget());
                deviceInfoWxpubCacheDto.setConfigId(wxpubInfoEntity.getConfigId());
                deviceInfoWxpubCacheDto.setDeviceId(wxpubInfoEntity.getDeviceId());
                deviceInfoWxpubCacheDto.setDeviceUniqueId(wxpubInfoEntity.getId());
                deviceInfoWxpubCacheDto.setMsgHandler(DeviceTypeEnum.WX_PUB.getId());
                deviceInfoWxpubCacheDto.setDeviceAuths(deviceProductAuthList);
                if (deviceProductAuthList != null && deviceProductAuthList.size() > 0) {
                    deviceInfoWxpubCacheDto.setExpireTime(deviceProductAuthList.get(0).getExpireTime());
                }
                //更新PC端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), wxpubInfoEntity.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoWxpubCacheDto)));
            }
        }

    }

    @Override
    public void updateWxpubObject(WxpubInfoUpdateSingleDto dto) {

        //查询机器人信息
        WxpubInfoEntity wxpubInfoEntity = mapper.queryObject(dto.getId());
        if (wxpubInfoEntity == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该公众号不存在");
        }

        //判断是否修改了配置方案id,如果修改了配置方案id,则需要判断配置方案里会员类型组是否不一样，如果不一样，则不能修改
        if (dto.getConfigId().longValue() != Tools.getLong(wxpubInfoEntity.getConfigId())) {
            ConfigPlan configPlanOld = configPlanMapper.selectById(wxpubInfoEntity.getConfigId(), wxpubInfoEntity.getMerId());
            ConfigPlan configPlanNew = configPlanMapper.selectById(dto.getConfigId(), dto.getMerId());
            if (configPlanOld != null && configPlanNew != null) {
                if(Tools.getLong(configPlanOld.getUserTypeGroupId()).longValue() != Tools.getLong(configPlanNew.getUserTypeGroupId()).longValue()) {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新修改的配置方案里的会员类型组和旧配置方案里会员类型组不一样");
                }
            }
        }


        //查询缓存并进行修改

        WxpubInfoEntity entity = JSONObject.parseObject(JSON.toJSONString(dto), WxpubInfoEntity.class);

        mapper.updateWxpubObject(entity);

        //根据id进行查询如果有对应缓存则修改 ,如果没有则进行添加
        Long id = dto.getId();

        //缓存处理 .
        Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id));
        if (object == null) {
            DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(JSON.toJSONString(wxpubInfoEntity), DeviceInfoWxpubCacheDto.class);

            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id), JSONObject.toJSONString(deviceInfoWxpubCacheDto));

        } else {
            DeviceInfoWxpubCacheDto deviceInfoWxpubCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoWxpubCacheDto.class);

            deviceInfoWxpubCacheDto.setConfigId(dto.getConfigId());

            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXPUB.getKey(), id), JSONObject.toJSONString(deviceInfoWxpubCacheDto));
        }
    }

    @Override
    public void posterUpdate(WxpubPosterDto wxpubPosterDto) {
        //查询缓存并进行修改

        WxpubInfoEntity entity = JSONObject.parseObject(JSON.toJSONString(wxpubPosterDto), WxpubInfoEntity.class);

        mapper.updateWxpubPoster(entity);
    }

}
